package br.com.vantagensaki.utils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DataUtil {

    private static SimpleDateFormat sdf_data_simples = new SimpleDateFormat("dd/MM/yyyy");
    private static SimpleDateFormat sdf_hora_simples = new SimpleDateFormat("HH:mm:ss");
    private static SimpleDateFormat sdf_hora_minuto_simples = new SimpleDateFormat("HH:mm");
    private static SimpleDateFormat sdf_data_hora = new SimpleDateFormat("HH");
    private static SimpleDateFormat sdf_data_minuto = new SimpleDateFormat("mm");
    private static SimpleDateFormat sdf_data_segundo = new SimpleDateFormat("ss");
    private static SimpleDateFormat sdf_data_dia = new SimpleDateFormat("dd");
    private static SimpleDateFormat sdf_data_mes_extenso = new SimpleDateFormat("MMMMM", new Locale("pt", "BR"));
    private static SimpleDateFormat sdf_data_mes = new SimpleDateFormat("MM");
    private static SimpleDateFormat sdf_data_ano = new SimpleDateFormat("yyyy");

    public DataUtil() {
    }

    public static boolean validaIntervaloDeHoras(Date horaInicio, Date horaFim) {
        Calendar inicio = setData01_01_2009(horaInicio);
        Calendar fim = setData01_01_2009(horaFim);

        return inicio.before(fim);
    }

    public static String formatarDataCompleta(Calendar data) {
        Date dataDate = data.getTime();
        return sdf_data_dia.format(dataDate) + " de " + sdf_data_mes_extenso.format(dataDate) + " de " + sdf_data_ano.format(dataDate) + " às " + sdf_hora_simples.format(dataDate);
    }

    public static String formatarHorario(Date data) {
        return sdf_hora_minuto_simples.format(data);
    }

    public static Date formatarParaDate(String dataStr, String formato) throws java.text.ParseException {
        Pattern pattern = Pattern.compile(formato);
        Matcher matcher = pattern.matcher(dataStr);
        if (matcher.matches()) {
            return new SimpleDateFormat(formato).parse(dataStr);
        }
        return null;
    }

    /**
     * <b>Autor:</b> Mário
     * <br/>
     * Retorna o número de semanas entre uma data e outra
     *
     * @param Calendar data1
     * @param Calendar data2
     * @return boolean
     */
    public static int numeroSemanas(Calendar data1, Calendar data2) {

        data1 = new GregorianCalendar(data1.get(Calendar.YEAR), data1.get(Calendar.MONTH), data1.get(Calendar.DAY_OF_MONTH));
        data2 = new GregorianCalendar(data2.get(Calendar.YEAR), data2.get(Calendar.MONTH), data2.get(Calendar.DAY_OF_MONTH));

        long ms;

        //subtrai a menor data da maior
        if (data1.after(data2)) {
            ms = data1.getTimeInMillis() - data2.getTimeInMillis();

        } else {
            ms = data2.getTimeInMillis() - data1.getTimeInMillis();

        }

        //calcula o numero de semanas
        return (int) (ms / (1000 * 3600 * 24 * 7));
    }

    public static int numeroSemanas(Date data1, Date data2) {
        Calendar c1 = new GregorianCalendar();
        c1.setTime(data1);

        Calendar c2 = new GregorianCalendar();
        c2.setTime(data2);

        return numeroSemanas(c1, c2);
    }

    /**
     * <b>Autor:</b> Mário
     * <br/>
     * Retorna true caso as datas tenham o mesmo dia, mes e ano
     *
     * @param Calendar data1
     * @param Calendar data2
     * @return boolean
     */
    public static boolean datasIguais(Calendar data1, Calendar data2) {
        if (data1.get(Calendar.DAY_OF_MONTH) != data2.get(Calendar.DAY_OF_MONTH)) {
            return false;
        }
        if (data1.get(Calendar.MONTH) != data2.get(Calendar.MONTH)) {
            return false;
        }
        if (data1.get(Calendar.YEAR) != data2.get(Calendar.YEAR)) {
            return false;
        }
        return true;
    }

    public static boolean datasIguais(Date data1, Date data2) {
        Calendar calendar1 = dateToCalendar(data1);
        Calendar calendar2 = dateToCalendar(data2);
        return datasIguais(calendar1, calendar2);
    }

//    /**
//     * <b>Autor:</b> Walanem
//     * <br/>
//     * Retorna 0 se a primeira data eh menor que a segunda. Caso contrario, retorna 1
//     *
//     * @param Calendar data1
//     * @param Calendar data2
//     * @return boolean
//     */
//    public static int comparaDatas(Calendar calendar1, Calendar calendar2) {
//
//        if (calendar1.get(Calendar.YEAR) < calendar2.get(Calendar.YEAR)) {
//            return 0;
//        }
//        if (calendar1.get(Calendar.MONTH) < calendar2.get(Calendar.MONTH)) {
//            if (calendar1.get(Calendar.DAY_OF_MONTH) < calendar2.get(Calendar.DAY_OF_MONTH)) {
//                return 0;
//            }
//        } else {
//            if (calendar1.get(Calendar.DAY_OF_MONTH) > calendar2.get(Calendar.DAY_OF_MONTH)) {
//                return 0;
//            }
//        }
//        return 1;
//    }
    public static Calendar dateToCalendar(Date dt) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(dt);
        return gc;
    }

    /**
     * <b>Autor:</b> Mário
     * <br/>
     * Compara dois intervalos de horario e verifica se há conflito.
     *
     * @param horarioInicial1
     * @param horarioFinal1
     * @param horarioInicial2
     * @param horarioFinal2
     * @return true caso os horarios sejam conflitantes
     */
    public static boolean horariosConflitantes(Date horarioInicial1, Date horarioFinal1,
            Date horarioInicial2, Date horarioFinal2) {

        //passando para calendar e setando dia, mes e ano iguais
        //para poder usar o after e before do calendar
        Calendar calendarInicial1 = dateToCalendar(horarioInicial1);
        calendarInicial1.set(2009, 01, 01);
        Calendar calendarFinal1 = dateToCalendar(horarioFinal1);
        calendarFinal1.set(2009, 01, 01);
        Calendar calendarInicial2 = dateToCalendar(horarioInicial2);
        calendarInicial2.set(2009, 01, 01);
        Calendar calendarFinal2 = dateToCalendar(horarioFinal2);
        calendarFinal2.set(2009, 01, 01);



        //verificando se o horario inicial de um é igual do outro
        if (calendarInicial1.get(Calendar.HOUR_OF_DAY) == calendarInicial2.get(Calendar.HOUR_OF_DAY) &&
                calendarInicial1.get(Calendar.MINUTE) == calendarInicial2.get(Calendar.MINUTE)) {
            return true;
        }
        //verificando se o horario final de um é igual do outro
        if (calendarFinal1.get(Calendar.HOUR_OF_DAY) == calendarFinal2.get(Calendar.HOUR_OF_DAY) &&
                calendarFinal1.get(Calendar.MINUTE) == calendarFinal2.get(Calendar.MINUTE)) {
            return true;
        }

        if (calendarInicial1.after(calendarInicial2)) {
            //troca inicio1 com inicio2
            Calendar temp = calendarInicial1;
            calendarInicial1 = calendarInicial2;
            calendarInicial2 = temp;

            //troca final1 com final2
            temp = calendarFinal1;
            calendarFinal1 = calendarFinal2;
            calendarFinal2 = temp;

        }

        //verificando se o horariofinal2 esta entre horarioinicial1 e horariofinal1
        if (calendarFinal1.after(calendarInicial2)) {
            return true;
        }


        return false;
    }

    public static Calendar setData01_01_2009(Date dt) {
        Calendar calendar = dateToCalendar(dt);
        calendar.set(2009, 01, 01);
        return calendar;
    }
}
